#ifndef __CALL__HEADER__
#define __CALL__HEADER__

#include "paramconfig.h"
#include "common.h"

class BFCPClient;
class SipCall
{
public:
    enum State
    {
        CALL_STATUS_IDLE,       // UAC/UAS
        CALL_STATUS_CALLING,    // UAC
        CALL_STATUS_INCOMING,   // UAS
        CALL_STATUS_100Tring,   // UAC
        CALL_STATUS_180Ring,    // UAC
        CALL_STATUS_200OK,      // UAC
        CALL_STATUS_ANSWERED,   // UAS
        CALL_STATUS_INCALL,     // UAC/UAS
        CALL_STATUS_FAIL,       // UAC/UAS
        CALL_STATUS_TERMINATE,  // UAC/UAS
        CALL_STATUS_COMPLETE    // UAC/UAS
    };
    SipCall(eXosip_t* ctx, const ConfigParam& param);
    ~SipCall();

    void updateNatInfo(const std::string& nataddress, int natport);

    bool sendOffer(const std::string& targetid, const std::string& sdp);
    bool sendAck(int tid);
    void onOffer(const eXosip_event* const osipEvt);
    void on100(const eXosip_event* const osipEvt);
    void on180(const eXosip_event* const osipEvt);
    void onAnswer(const eXosip_event* const osipEvt);
    void onFail(const eXosip_event* const osipEvt);
    void onAck(const eXosip_event* const osipEvt);
    void onCancel(const eXosip_event* const osipEvt);
    void onBye(const eXosip_event* const osipEvt);
    void releaseCall(const eXosip_event* const osipEvt);
    void terminate(const std::string& reason);

    bool isConnected() const;
    bool isIncall() const;

    static std::string toString(State state);
    void transitionState(State s);

    bool sendCallRequest(const std::string& method, const std::string& contenttype, const std::string& msg, void* appdata = NULL);
    bool sendCallResponse(int did, int cid, int tid, int statuscode, const std::string& contenttype, const std::string& msg);

protected:
    bool sendAnswer(const eXosip_event* const osipEvt);

protected:
    const ConfigParam&  mParam;
    eXosip_t*           mSipCtx;
    State               mCallState;
    int                 mDID;
    int                 mCID;
    std::string         mNatAddress;
    int                 mNatPort;
    BFCPClient*         mBfcpClient;
};

#endif // #ifndef __CALL__HEADER__
